/********************************************
 * 功能说明:
 * 模块名称:
 * 系统名称:
 * 软件版权: Frank
 * 系统版本: 1.0.0
 * 开发人员: Frank
 * 开发时间: 2019/12/12 10:46
 * 审核人员:
 * 相关文档:
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.spring.arch.uaa.web.converter;

import com.spring.arch.uaa.dto.EmployeeDTO;
import com.spring.arch.uaa.errorcode.UaaErrorCode;
import com.spring.arch.common.exception.ExceptionHolder;
import com.spring.arch.uaa.bean.EmployeeBean;
import com.spring.arch.uaa.dto.EmployeeDTO;
import com.spring.arch.uaa.enums.CreateType;
import com.spring.arch.uaa.model.*;
import com.spring.arch.uaa.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

import static com.spring.arch.uaa.errorcode.UaaErrorCode.*;


/**
 * 人员转换器
 *
 * @author Frank
 * @version 1.0.0.1
 * @since 2019/12/12 10:46
 */
@Component
public class EmployeeConverter {

    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private TenantRepository tenantRepository;
    @Autowired
    private ProjectRepository projectRepository;
    @Autowired
    private OrganizationRepository organizationRepository;
    @Autowired
    private TenantEmployeeRepository tenantEmployeeRepository;

    public EmployeeBean toBean(EmployeeDTO dto) {
        if (dto.isNew()) {
            return constructBean(dto);
        } else {
            return updateBean(dto);
        }
    }

    private EmployeeBean constructBean(EmployeeDTO dto) {
        EmployeeBean bean = new EmployeeBean();
        @NotNull UUID tenantId = dto.getTenantId();
        Tenant tenant = tenantRepository.findById(tenantId)
                .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001001001, String.valueOf(tenantId)));
        bean.setTenant(tenant);
        UUID organizationId = dto.getOrganizationId();
        if (organizationId != null) {
            Organization organization = organizationRepository.findById(organizationId)
                    .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001003001, String.valueOf(organizationId)));
            bean.setOrganization(organization);
        }
        UUID projectId = dto.getProjectId();
        if (projectId != null) {
            Project project = projectRepository.findById(projectId)
                    .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001002001, String.valueOf(projectId)));
            bean.setProject(project);
        }

        this.dtoToBean(dto, bean);
        return bean;
    }

    private EmployeeBean updateBean(EmployeeDTO dto) {
        EmployeeBean bean = new EmployeeBean();
        this.dtoToBean(dto, bean);
        return bean;
    }

    private void dtoToBean(final EmployeeDTO dto, final EmployeeBean bean) {
        List<UUID> roleIds = dto.getRoleIds();
        if (!CollectionUtils.isEmpty(roleIds)) {
            List<Role> roles = new ArrayList<>(roleIds.size());
            roleIds.forEach(roleId -> {
                Optional<Role> optional = roleRepository.findById(roleId);
                optional.ifPresent(roles::add);
            });
            bean.setRoles(roles);
        }
        bean.setTenantEmployee(dtoToEmployee(dto, bean.getTenant()));
    }


    private TenantEmployee dtoToEmployee(final EmployeeDTO dto, final Tenant tenant) {
        TenantEmployee employee;
        if (dto.isNew()) {
            employee = new TenantEmployee();
            employee.setTenant(tenant);
        } else {
            employee = this.tenantEmployeeRepository.findById(dto.getId())
                    .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001004001, String.valueOf(dto.getId())));
        }

        employee.setCode(dto.getCode());
        employee.setName(dto.getName());
        employee.setMobile(dto.getMobile());
        employee.setGender(dto.getGender());
        employee.setEmail(dto.getEmail());
        employee.setCreateType(CreateType.SAVE);
        employee.setPhotos(dto.getPhotos());

        return employee;
    }
}
